#include "BellmanFordTest.h"
#include "DijkstraTest.h"
#include "FloydWarshallTest.h"
#include "JohnsonTest.h"
#include "Generator.h"
#include "BreadthFirstSearch.h"

#include <iostream>
#include <iomanip>

using namespace zbp;

void test_for_nodes_count(int density);

int main()
{
	if (false)
	{
		int nodes_count = 5000;
		int adjacent_count = 4000;
		int negative_count = 1000000000;
		int max_weight = 20;

		SimpleGraph simple_graph;
		CompleteGraph<int> complete_graph(nodes_count);

		BoostEdge* boost_edges = new BoostEdge[nodes_count * adjacent_count];
		int* boost_weights = new int[nodes_count * adjacent_count];	
	
		zbp::Generator g;
		g.generate_graph(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count, max_weight, negative_count);

		vector<int> d,p;
		simple_graph.dijkstra(1,d,p);

		//bellman_ford_tests_run(simple_graph, boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count,1);
		//dijkstra_tests_run(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count * nodes_count, 0);
		//floyd_warshall_tests_run(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count * nodes_count);
		//johnson_tests_run(simple_graph, boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count);

		delete boost_edges;
		delete boost_weights;
	}
	else
	{
		test_for_nodes_count(100);
		test_for_nodes_count(60);
		test_for_nodes_count(20);
	}

	system("pause");
	return 0;
}

void test_for_nodes_count(int density)
{
	int min_nodes_count = 100;
	int step = 200;
	int intervals_count = 8;

	int max_nodes_count = min_nodes_count + intervals_count * step;
	int nodes_count = min_nodes_count;

	int adjacent_count_percent = density;
	int adjacent_count = nodes_count * adjacent_count_percent/100;
	int negative_count = 1000000000;
	int max_weight = 20;

	/*SimpleGraph simple_graph;
	CompleteGraph<int> complete_graph(min_nodes_count);

	BoostEdge* boost_edges = new BoostEdge[max_nodes_count * adjacent_count];
	int* boost_weights = new int[max_nodes_count * adjacent_count];	
	*/
	zbp::Generator g;
	//g.generate_graph(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count, max_weight, negative_count);*/

	//simple_graph.display();
	//complete_graph.display();

	int col_width = 6;

	cout << "Test - density " << density << endl << endl;
	cout << std::setw(col_width) << "n" << ";"
	     << std::setw(col_width) << "adj" << ";"
		 << std::setw(col_width+2) << "s" << ";"
		 //<< std::setw(col_width) << "sinit" << ";"
		 //<< std::setw(col_width) << "c" << ";"
		 //<< std::setw(col_width) << "cinit" << ";"
		 << std::setw(col_width) << "boost" << ";" << endl;

	double sg=0, sg_init=0, cg=0, cg_init=0, boost=0;

	for (int i = 0; i < intervals_count; i++)
	{
		adjacent_count = nodes_count * adjacent_count_percent/100;

		//g.add_nodes(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count, max_weight, negative_count, step);

		SimpleGraph simple_graph;
		CompleteGraph<int> complete_graph(nodes_count);
		BoostEdge* boost_edges = new BoostEdge[nodes_count * adjacent_count];
		int* boost_weights = new int[nodes_count * adjacent_count];	
		g.generate_graph(simple_graph, complete_graph, boost_edges, boost_weights, nodes_count, adjacent_count, max_weight, negative_count);

		//simple_graph.display();
		//complete_graph.display();

		//sg = floyd_warshall_SimpleGraph_test(simple_graph, false);
		//sg_init = floyd_warshall_initialized_SimpleGraph_test(simple_graph, false);
		//cg = floyd_warshall_CompleteGraph_test(complete_graph, false);
		//cg_init = floyd_warshall_initialized_CompleteGraph_test(complete_graph, false);
		//boost = floyd_warshall_boost_test(boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count, false);

		//sg = johnson_SimpleGraph_test(simple_graph, false);
		//sg_init = johnson_initialized_SimpleGraph_test(simple_graph, false);
		//boost = johnson_boost_test(boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count, false);

		//sg = n_dijkstra_SimpleGraph_test(simple_graph, false);
		//cg = n_dijkstra_CompleteGraph_test(complete_graph, false);
		//boost = n_dijkstra_boost_test(boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count, false);

		sg = n_bellman_ford_SimpleGraph_test(simple_graph, false);
		cg = n_bellman_ford_CompleteGraph_test(complete_graph, false);
		boost = n_bellman_ford_boost_test(boost_edges, boost_weights, nodes_count, adjacent_count *nodes_count, false);
		
		//sg = breadth_search_first_SimpleGraph_test(simple_graph, false, 0);
		//boost = breadth_search_first_boost_test(0, boost_edges, boost_weights, nodes_count, adjacent_count * nodes_count, false);

		cout << std::setw(col_width) << nodes_count << ";"
			 << std::setw(col_width) << adjacent_count << ";";

		cout << std::setw(col_width+2) << sg << ";"
			 //<< std::setw(col_width) << sg_init << ";"
			 << std::setw(col_width) << cg << ";"
			 //<< std::setw(col_width) << cg_init << ";"
			 << std::setw(col_width) << boost << ";" << endl;

		nodes_count += step;

		delete boost_edges;
		delete boost_weights;
	}
}